package services

import (
	"context"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/go-kit/kit/endpoint"
	"github.com/go-kit/kit/log"
	"gokit/util"
	"golang.org/x/time/rate"
	"strconv"
)

type UserRequest struct {
	Uid    int    `json:"uid"`
	Method string `json:"method"`
	Token  string `json:"token"`
}

type UserResponse struct {
	Result string `json:"result"`
}

// CheckTokenMiddleware token验证中间件
func CheckTokenMiddleware() endpoint.Middleware { //Middleware type Middleware func(Endpoint) Endpoint
	return func(next endpoint.Endpoint) endpoint.Endpoint { //Endpoint type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			r := request.(UserRequest) //通过类型断言获取请求结构体
			uc := UserClaim{}
			//下面的r.Token是在代码DecodeUserRequest那里封装进去的
			getToken, err := jwt.ParseWithClaims(r.Token, &uc, func(token *jwt.Token) (i interface{}, e error) {
				return []byte(secKey), err
			})
			fmt.Println(err)
			if getToken != nil && getToken.Valid { //验证通过
				newCtx := context.WithValue(ctx, "LoginUser", getToken.Claims.(*UserClaim).Uname) // context 添加设置 键值
				return next(newCtx, request)
			} else {
				return nil, util.NewMyError(403, "error token")
			}

			//logger.Log("method", r.Method, "event", "get user", "userid", r.Uid)

		}
	}
}

// UserServiceLogMiddleware 日志中间件
func UserServiceLogMiddleware(logger log.Logger) endpoint.Middleware {
	// 整合日志
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			r := request.(UserRequest)
			logger.Log("method", r.Method, "event", "get user", "userid", r.Uid) // 打印日志
			return next(ctx, request)
		}
	}
}

// RateLimit 加入限流功能中间件
func RateLimit(limiter *rate.Limiter) endpoint.Middleware { // limiter：令牌桶
	return func(next endpoint.Endpoint) endpoint.Endpoint { // next：GenUserEndPoint，RateLimit(limiter)(GenUserEndPoint)
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			if !limiter.Allow() {
				//return nil, errors.New("too many request")
				// 自定义错误返回
				return nil, util.NewMyError(429, "too many request")
			}
			return next(ctx, request) // next 就是GenUserEndPoint
		}
	}
}

// RateLimit(limiter)(GenUserEndPoint) // 类似 js 里的 fn(1)(2)

// GenUserEndPoint controller 层，根据请求调用不同的Service处理业务逻辑
func GenUserEndPoint(userService IUserService) endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
		fmt.Println("当前登录用户名是", ctx.Value("LoginUser")) // 获取 context 内的值
		r := request.(UserRequest) //通过类型断言获取请求结构体
		var result string
		if r.Method == "GET" {
			result = userService.GetName(r.Uid) + strconv.Itoa(util.ServicePort) // 调用不同的Service处理业务逻辑

		} else if r.Method == "DELETE" {
			err = userService.DelUser(r.Uid)
			if err != nil {
				result = err.Error()
			} else {
				result = fmt.Sprintf("userid为%d的用户删除成功", r.Uid)
			}
		}

		return UserResponse{Result: result}, nil
	}
}
